# -*- coding: utf-8 -*-
# @author: Longxing Tan, tanlongxing888@163.com
# @date: 2020-01

import pandas as pd
import numpy as np


def transform2_lagged_feature(x, window_sizes):
    '''
    create historical lagged value as features
    :return:
    '''
    if isinstance(x, pd.Series):
        x = pd.DataFrame(x.values, index=range(len(x)), columns=["Feature"])
    inputs_lagged = pd.DataFrame()
    init_value = x.iloc[0]
    for window_size in range(1, window_sizes + 1):
        inputs_roll = np.roll(x, window_size, axis=0)
        inputs_roll[:window_size] = init_value
        inputs_roll = pd.DataFrame(inputs_roll, index=x.index,
                                   columns=[i + '_lag{}'.format(window_size) for i in x.columns])
        inputs_lagged = pd.concat([inputs_roll, inputs_lagged], axis=1)
    return inputs_lagged


def transform2_lagged_feature_md(x, window_sizes, out_windows_size):
    '''
    create historical lagged value as features
    :return:
    '''
    if isinstance(x, pd.Series):
        x = pd.DataFrame(x.values, index=range(len(x)), columns=["Feature"])
    inputs_lagged = None
    # init_value = x.iloc[0]
    for start_index in range(x.shape[0] - window_sizes - out_windows_size - 1):
        temp_x = x[start_index:start_index+window_sizes].values
        temp_x = temp_x[np.newaxis, :]
        if isinstance(inputs_lagged, np.ndarray):
            inputs_lagged = np.concatenate((inputs_lagged, temp_x))
        else:
            inputs_lagged = temp_x
    return inputs_lagged



def multi_step_y(y, predict_window, predict_gap=1):
    if isinstance(y, pd.DataFrame):
        y = y.values
    outputs = np.full((y.shape[0], predict_window, y.shape[1]), np.nan)
    # y = y[:, 0]
    for i in range(predict_window):
        outputs_column = np.roll(y, -(i+predict_gap-1)).astype(np.float)
        if (i+predict_gap-1) != 0:
            outputs_column[-(i+predict_gap-1):] = np.nan
        outputs[:, i] = outputs_column
    outputs = outputs.reshape((outputs.shape[0], -1, 1))
    return outputs


def multi_step_y_md(y, predict_window, input_window=40):
    if isinstance(y, pd.DataFrame):
        y = y.values
    # outputs = np.full((y.shape[0], predict_window, y.shape[1]), np.nan)
    outputs = None

    for start_index in range(input_window, y.shape[0] - predict_window- 1):
        temp_y = y[start_index:start_index+predict_window]
        temp_y = temp_y[np.newaxis, :]
        if isinstance(outputs, np.ndarray):
            outputs = np.concatenate((outputs, temp_y))
        else:
            outputs = temp_y
    return outputs


def simple_moving_average(x):
    pass



def postprocess(x, y):
        if isinstance(x, pd.DataFrame):
            x = x.values
        if len(x.shape) == 2:
            x = x[..., np.newaxis]
        if isinstance(y, pd.DataFrame):
            y = y.values
        if len(y.shape) == 2:
            y = y[..., np.newaxis]

        filter = (np.isnan(y)).any(axis=1)[:, 0]  # remove the nan in target
        x = x[~filter]
        y = y[~filter]
        return x, y